/*
 * @Author: jack_yang98 1246900429@qq.com
 * @Date: 2024-08-03 15:27:00
 * @LastEditors: jack_yang98 1246900429@qq.com
 * @LastEditTime: 2024-08-03 18:03:15
 * @FilePath: /gateway/app/app_buffer.c
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "app_buffer.h"
#include "string.h"
#include "stdlib.h"
#include "thirdparty/log/log.h"
#include <pthread.h>

static pthread_mutex_t lock_initializer = PTHREAD_MUTEX_INITIALIZER;

int App_Buffer_init(Buffer *buffer, int size)
{
    buffer->ptr = malloc(size);
    if (!buffer->ptr)
    {
        log_warn("创建缓存区失败 %p", buffer);
        return -1;
    }
   
    memcpy(&buffer->lock, &lock_initializer, sizeof(pthread_mutex_t));
    buffer->size = size;
    buffer->start = 0;
    buffer->len = 0;
    log_debug("创建成功%p", buffer);

    return 0;
}

int App_Buffer_read(Buffer *buffer, void *buf, int len)
{

    if (!buffer || !buf)
    {
        log_warn("Buffer 或 buf 为空");
        return -1;
    }

    if (len == 0)
    {
        return 0;
    }
    pthread_mutex_lock(&buffer->lock);
    if (len > buffer->len)
    {
        len = buffer->len;
    }

    if (buffer->start + len <= buffer->size)
    {
        memcpy(buf, buffer->ptr + buffer->start, len);
        buffer->start += len;
    }
    else
    {
        // 读两次
        // 第一次读取的长度为
        int first_len = buffer->size - buffer->start;
        memcpy(buf, buffer->ptr + buffer->start, first_len);
        memcpy(buf + first_len, buffer->ptr, len - first_len);
        buffer->start = len - first_len;
    }
    buffer->len -= len;

    pthread_mutex_unlock(&buffer->lock);
    log_trace("Buffer status after read: start %d, len %d", buffer->start, buffer->len);

    return 0;
}

int App_Buffer_write(Buffer *buffer, void *buf, int len)
{
    if (!buffer || !buf)
    {
        log_warn("Buffer 或 buf 为空");
        return -1;
    }
    if (len == 0)
    {
        return 0;
    }
    if (len > buffer->size - buffer->len)
    {
        log_warn("剩余空间不足无法写入 %p", buffer);
        return -1;
    }
    pthread_mutex_lock(&buffer->lock);
    // 首先找到写入起点
    int wirte_offset = buffer->start + buffer->len;
    if (wirte_offset > buffer->size)
    {
        wirte_offset -= buffer->size;
    }

    // 判断写入起点到尾部还有多少空间
    if (wirte_offset + len <= buffer->size)
    {
        memcpy(buffer->ptr + wirte_offset, buf, len);
    }
    else
    {
        // 先写多少个
        int residue = buffer->size - wirte_offset;
        memcpy(buffer->ptr + wirte_offset, buf, residue);
        memcpy(buffer->ptr, buf + residue, len - residue);
    }

    buffer->len += len;
    pthread_mutex_unlock(&buffer->lock);
    log_trace("Buffer status after wirte: start %d, len %d", buffer->start, buffer->len);
    return 0;
}

int App_Buffer_close(Buffer *buffer)
{
    if (!buffer->ptr)
    {
        log_warn("清除缓存区失败 %p", buffer);
        return -1;
    }
    free(buffer->ptr);

    buffer->ptr = NULL;
    buffer->len = 0;
    buffer->size = 0;
    buffer->start = 0;

    return 0;
}

